package com.power.util;

/**
 * 对象操作类
 * @author fc
 * @Date 2010-10-17
 */
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PojoPropertiesUtil {
	private static PojoPropertiesUtil instance;

	private PojoPropertiesUtil() {

	}

	public static PojoPropertiesUtil getInstance() {
		if (null == instance)
			instance = new PojoPropertiesUtil();
		return instance;
	}

	/**
	 * 将源对象中的值存入目标对象
	 * 
	 * @param targetObj
	 *            目标对象
	 * @param sourceObj
	 *            源对象
	 * @return targetObj
	 */
	@SuppressWarnings("unchecked")
	public Object copyProperties(Object targetObj, Object sourceObj) {
		try {
			Class targetClass = targetObj.getClass();
			Class sourceClass = sourceObj.getClass();
			Field[] sourceFields, targetFields;
			sourceFields = sourceClass.getDeclaredFields();
			targetFields = targetClass.getDeclaredFields();
			for (int i = 0; i < sourceFields.length; i++) {
				Field field = sourceFields[i];
				Field targetField = targetFields[i];
				field.setAccessible(true);
				targetField.setAccessible(true);
				if (null == field.get(sourceObj))
					continue;
				if (null != targetField.get(targetObj)) {
					continue;
				}
				String fieldName = field.getName();
				Object value = field.get(sourceObj);
				Method getMethod = targetClass.getMethod("get"
						+ fieldName.substring(0, 1).toUpperCase()
						+ fieldName.substring(1));
				Method setMethod = null;
				Class paramType = getMethod.getReturnType();
				String pT = paramType.getName();
				Class[] obj = null;
				if ("java.lang.Integer".equals(pT)) {
					obj = new Class[] { Integer.class };
				} else if (("java.lang.String").equals(pT)) {
					obj = new Class[] { String.class };
				} else if (("java.lang.Float").equals(pT)) {
					obj = new Class[] { Float.class };
				} else if (("java.lang.Double").equals(pT)) {
					obj = new Class[] { Double.class };
				} else if ("java.util.Date".equals(pT)) {
					obj = new Class[] { Date.class };
				} else {
					continue;
				}
				setMethod = targetClass.getMethod("set"
						+ fieldName.substring(0, 1).toUpperCase()
						+ fieldName.substring(1), obj);
				setMethod.invoke(targetObj, value);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return targetObj;
	}

	/**
	 * 未完成
	 * 
	 * @param conditionStr
	 * @param pojoObj
	 * @param valueArray
	 * @return
	 * 
	 * @SuppressWarnings("unchecked") public Object formatArray2POJO(String
	 *                                conditionStr, Object pojoObj, Object[]
	 *                                valueArray) { try { String[]
	 *                                conditionArray = conditionStr.split(",");
	 *                                Class targetClass = pojoObj.getClass();
	 *                                for (int i = 0; i < conditionArray.length;
	 *                                i++) { String fieldName = ""; String
	 *                                conditionName = conditionArray[i];
	 *                                String[] tempArray =
	 *                                conditionName.split("."); String tempName =
	 *                                ""; if (tempArray.length > 1) tempName =
	 *                                tempArray[1]; else if (tempArray.length >
	 *                                0) tempName = tempArray[0]; tempName =
	 *                                tempName.trim(); fieldName = tempName; if
	 *                                (tempName.indexOf("as") != -1) { fieldName =
	 *                                tempName.substring(tempName.indexOf("as") +
	 *                                1); } else { int index =
	 *                                tempName.indexOf(" "); if (index > -1)
	 *                                fieldName = tempName
	 *                                .substring(tempName.indexOf(" ") + 1); }
	 *                                fieldName = fieldName.trim();
	 *                                System.out.println(fieldName); Method
	 *                                getMethod = targetClass.getMethod("get" +
	 *                                fieldName.substring(0, 1).toUpperCase() +
	 *                                fieldName.substring(1)); Method setMethod =
	 *                                null; Class paramType =
	 *                                getMethod.getReturnType(); String pT =
	 *                                paramType.getName(); Class[] obj = null;
	 *                                if ("java.lang.Integer".equals(pT)) { obj =
	 *                                new Class[] { Integer.class }; } else if
	 *                                (("java.lang.String").equals(pT)) { obj =
	 *                                new Class[] { String.class }; } else if
	 *                                (("java.lang.Float").equals(pT)) { obj =
	 *                                new Class[] { Float.class }; } else if
	 *                                (("java.lang.Double").equals(pT)) { obj =
	 *                                new Class[] { Double.class }; } else if
	 *                                ("java.util.Date".equals(pT)) { obj = new
	 *                                Class[] { Date.class }; } else { continue; }
	 *                                try { setMethod =
	 *                                targetClass.getMethod("set" +
	 *                                fieldName.substring(0, 1).toUpperCase() +
	 *                                fieldName.substring(1), obj);
	 *                                setMethod.invoke(pojoObj, valueArray[i]); }
	 *                                catch (Exception e) { e.printStackTrace();
	 *                                continue; } } } catch (Exception e) {
	 *                                e.printStackTrace(); } return pojoObj; }
	 */

	/**
	 * 合并同类型的POJO(暂时未对float、double型数据进行累计计算)
	 * 
	 * @param trtjbb
	 *            目标对象
	 * @param buff
	 *            临时存放数据对象，其类型需和目标对象一致
	 * @param classPath
	 *            目标对象所对应POJO（实体bean）路径
	 * @param notIncludeParams
	 *            不需要处理的属性名数组
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Object bulidStaticsPOJO(Object trtjbb, Object buff,
			String classPath, String[] notIncludeParams) {
		Class t;
		try {
			String[] notIncludeMethodNameArray = bulidMethodNameArrayFactory(notIncludeParams);
			List arrContent = null;// 定义集合
			arrContent = Arrays.asList(notIncludeMethodNameArray);// 转化为集合
			t = Class.forName(classPath);
			Method[] methodArray = t.getMethods();
			for (Method me : methodArray) {
				String methodName = me.getName();
				if (arrContent.contains(methodName))
					continue;
				if (methodName.startsWith("set")) {
					Method getMethod = null;
					getMethod = t.getMethod("g" + methodName.substring(1));
					Class paramType = getMethod.getReturnType();
					String typeName = paramType.getName();
					Object bufValue;
					Object value;
					try {
						bufValue = getMethod.invoke(buff);
						value = getMethod.invoke(trtjbb);
					} catch (Exception e) {
						continue;
					}
					if ("java.lang.Integer".equals(typeName)) {
						Integer totalValue = (null == (Integer) bufValue ? 0
								: (Integer) bufValue)
								+ (null == (Integer) value ? 0
										: (Integer) value);
						me.invoke(trtjbb, totalValue);
					} else if ("java.lang.Float".equals(typeName)) {
						Float totalValue = (null == (Float) bufValue ? 0
								: (Float) bufValue)
								+ (null == (Float) value ? 0 : (Float) value);
						me.invoke(trtjbb, new Float(new DecimalFormat("##.00")
								.format(totalValue)));
					} else if ("java.lang.Double".equals(typeName)) {
						Double totalValue = (null == (Double) bufValue ? 0
								: (Double) bufValue)
								+ (null == (Double) value ? 0 : (Double) value);
						me.invoke(trtjbb, new Double(new DecimalFormat("##.00")
								.format(totalValue)));
					} else {
						continue;
					}
				}
			}
		} catch (ClassNotFoundException e) {
		} catch (IllegalArgumentException e) {
		} catch (IllegalAccessException e) {
		} catch (InvocationTargetException e) {
		} catch (SecurityException e) {
		} catch (NoSuchMethodException e) {
		}
		return trtjbb;
	}

	private static String[] bulidMethodNameArrayFactory(String[] params) {
		String[] notIncludeMethodNameArray = new String[params.length];
		for (int i = 0; i < params.length; i++) {
			String paramName = params[i];
			notIncludeMethodNameArray[i] = "set"
					+ paramName.substring(0, 1).toUpperCase()
					+ paramName.substring(1);
		}
		return notIncludeMethodNameArray;
	}

	@SuppressWarnings("unchecked")
	public Object copyProperties(Object targetObj, Map<String, String> sourceObj) {
		try {
			Class targetClass = targetObj.getClass();
			Field[] sourceFields;
			sourceFields = targetClass.getDeclaredFields();
			for (int i = 0; i < sourceFields.length; i++) {
				Field field = sourceFields[i];
				field.setAccessible(true);
				String fieldName = field.getName();
				if (null == sourceObj.get(fieldName))
					continue;
				Object value = sourceObj.get(fieldName);
				Method setMethod = null;
				Class[] obj = null;
				obj = new Class[] { String.class };
				setMethod = targetClass.getMethod("set"
						+ fieldName.substring(0, 1).toUpperCase()
						+ fieldName.substring(1), obj);
				setMethod.invoke(targetObj, value.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return targetObj;
	}

}
